home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / oleo-1_4.lha / oleo-1.4 / date.c < prev    next >
C/C++ Source or Header  |  1993-05-13  |  8KB  |  387 lines

  1. /*    Copyright (C) 1990, 1992, 1993 Free Software Foundation, Inc.
  2.  
  3. This file is part of Oleo, the GNU Spreadsheet.
  4.  
  5. Oleo is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. Oleo is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with Oleo; see the file COPYING.  If not, write to
  17. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19.  
  20.  
  21. #include "funcdef.h"
  22. #include "sysdef.h"
  23.  
  24. #include "global.h"
  25. #include "cell.h"
  26. #include "eval.h"
  27. #include "errors.h"
  28.  
  29. struct value
  30.   {
  31.     int type;
  32.     union vals x;
  33.   };
  34.  
  35. #define Float    x.c_d
  36. #define String    x.c_s
  37. #define Int    x.c_l
  38. #define Value    x.c_i
  39. #define Rng    x.c_r
  40.  
  41.  
  42.  
  43. #ifdef __STDC__
  44. struct timeb;
  45. extern time_t get_date (char *, struct timeb *);
  46. extern time_t posixtime (char *);
  47. #else
  48. extern time_t get_date ();
  49. extern time_t posixtime ();
  50. #endif
  51.  
  52.  
  53.  
  54. /* These functions simply provide convenient syntax for expressing intervals 
  55.  * of time.
  56.  */
  57.  
  58. #ifdef __STDC__
  59. static long
  60. dt_hms_to_time (long h, long m, long s)
  61. #else
  62. static long
  63. dt_hms_to_time (h, m, s)
  64.      long h;
  65.      long m;
  66.      long s;
  67. #endif
  68. {
  69.   return ((h * 60) + m) * 60 + s;
  70. }
  71.  
  72. #ifdef __STDC__
  73. static long
  74. dt_dhms_to_time (long d, long h, long m, long s)
  75. #else
  76. static long
  77. dt_dhms_to_time (d, h, m, s)
  78.      long d;
  79.      long h;
  80.      long m;
  81.      long s;
  82. #endif
  83. {
  84.   return ((((d * 24) + h) * 60) + m) * 60 + s;
  85. }
  86.  
  87. #ifdef __STDC__
  88. static long
  89. dt_time_to_d (long t)
  90. #else
  91. static long
  92. dt_time_to_d (t)
  93.      long t;
  94. #endif
  95. {
  96.   return t / (60 * 60 * 24);
  97. }
  98.  
  99. #ifdef __STDC__
  100. static long
  101. dt_time_to_h (long t)
  102. #else
  103. static long
  104. dt_time_to_h (t)
  105.      long t;
  106. #endif
  107. {
  108.   return (t / (60 * 60)) % 24;
  109. }
  110.  
  111. #ifdef __STDC__
  112. static long
  113. dt_time_to_m (long t)
  114. #else
  115. static long
  116. dt_time_to_m (t)
  117.      long t;
  118. #endif
  119. {
  120.   return (t / 60) % 60;
  121. }
  122.  
  123. #ifdef __STDC__
  124. static long
  125. dt_time_to_s (long t)
  126. #else
  127. static long
  128. dt_time_to_s (t)
  129.      long t;
  130. #endif
  131. {
  132.   return t % 60;
  133. }
  134.  
  135.  
  136.  
  137. /* These relate time values to calendar dates using localtime, gmtime, 
  138.  * strftime, mktime, etc.
  139.  */
  140.  
  141. /* mktime: */
  142.  
  143.  
  144. #ifdef __STDC__
  145. static long
  146. dt_ymd_dst (long y, long mo, long d, long dst)
  147. #else
  148. static long
  149. dt_ymd_dst (y, mo, d, dst)
  150.      long y;
  151.      long mo;
  152.      long d;
  153.      long dst;
  154. #endif
  155. {
  156.   struct tm tm;
  157.   tm.tm_year = y - 1900;
  158.   tm.tm_mon = mo;
  159.   tm.tm_mday = d;
  160.   tm.tm_hour = 0;
  161.   tm.tm_min = 0;
  162.   tm.tm_sec = 0;
  163.   tm.tm_isdst = dst;
  164.   return mktime (&tm);
  165. }
  166.  
  167. #ifdef __STDC__
  168. static long
  169. dt_ymd (long y, long mo, long d)
  170. #else
  171. static long
  172. dt_ymd (y, mo, d)
  173.      long y;
  174.      long mo;
  175.      long d;
  176. #endif
  177. {
  178.   return dt_ymd_dst (y, mo, d, -1);
  179. }
  180.  
  181.  
  182.  
  183.  
  184. #define TM_ACCESS(FN,FIELD,TMFN)            \
  185. static long                        \
  186. FN (clk)                        \
  187.      long clk;                    \
  188. {                            \
  189.   time_t t = (time_t)clk;                \
  190.   struct tm * tm = TMFN(&t);                \
  191.   return (long)tm->FIELD;                \
  192. }
  193.  
  194. #define TM_ACCESS_LOCAL(FN,FIELD)  TM_ACCESS(FN, FIELD, localtime)
  195.  
  196. TM_ACCESS_LOCAL (dt_local_year, tm_year + 1900)
  197. TM_ACCESS_LOCAL (dt_local_month, tm_mon)
  198. TM_ACCESS_LOCAL (dt_local_date, tm_mday)
  199. TM_ACCESS_LOCAL (dt_local_hour, tm_hour)
  200. TM_ACCESS_LOCAL (dt_local_min, tm_min)
  201. TM_ACCESS_LOCAL (dt_local_sec, tm_sec)
  202. TM_ACCESS_LOCAL (dt_local_isdst, tm_isdst)
  203. TM_ACCESS_LOCAL (dt_local_yday, tm_yday)
  204. TM_ACCESS_LOCAL (dt_local_wday, tm_wday)
  205.  
  206.  
  207. #define TM_ACCESS_GMT(FN,FIELD)  TM_ACCESS(FN, FIELD, gmtime)
  208.  
  209. TM_ACCESS_GMT (dt_gmt_year, tm_year + 1900)
  210. TM_ACCESS_GMT (dt_gmt_month, tm_mon)
  211. TM_ACCESS_GMT (dt_gmt_date, tm_mday)
  212. TM_ACCESS_GMT (dt_gmt_hour, tm_hour)
  213. TM_ACCESS_GMT (dt_gmt_min, tm_min)
  214. TM_ACCESS_GMT (dt_gmt_sec, tm_sec)
  215. TM_ACCESS_GMT (dt_gmt_isdst, tm_isdst)
  216. TM_ACCESS_GMT (dt_gmt_yday, tm_yday)
  217. TM_ACCESS_GMT (dt_gmt_wday, tm_wday)
  218.  
  219.  
  220.  
  221. #ifdef __STDC__
  222. static char *
  223. dt_strftime (char * format, long clk)
  224. #else
  225. static char *
  226. dt_strftime (format, clk)
  227.      char * format;
  228.      long clk;
  229. #endif
  230. {
  231.   int len_used = 0;
  232.   int len = 32;
  233.   char * buf = (char *)ck_malloc (len);
  234.   time_t ck = (time_t)clk;
  235.   struct tm * tm = localtime (&ck);
  236.   while (!len_used)
  237.     {
  238.       len *= 2;
  239.       buf = (char *)ck_remalloc (buf, len);
  240.       len_used = strftime (buf, len - 1, format, tm);
  241.     }
  242.   if (len - 1 > len_used)
  243.     buf = (char *)ck_remalloc (buf, len_used + 1);
  244.   buf [len_used] = 0;
  245.   return buf;
  246. }
  247.  
  248.  
  249.  
  250. #ifdef __STDC__
  251. static long
  252. dt_get_date (char * date)
  253. #else
  254. static long
  255. dt_get_date (date)
  256.      char * date;
  257. #endif
  258. {
  259.   return get_date (date, NULL);
  260. }
  261.  
  262. #ifdef __STDC__
  263. static long
  264. dt_posix_date (char * date)
  265. #else
  266. static long
  267. dt_posix_date (date)
  268.      char * date;
  269. #endif
  270. {
  271.   return posixtime (date);
  272. }
  273.  
  274.  
  275.  
  276. static void
  277. l_l (fn, p)
  278.      long (*fn)();
  279.      struct value * p;
  280. {
  281.   p[0].Int = fn (p->Int);
  282. }
  283.  
  284. static void
  285. l_lll (fn, p)
  286.      long (*fn)();
  287.      struct value * p;
  288. {
  289.   p[0].Int = fn (p[0].Int, p[1].Int, p[2].Int);
  290. }
  291.  
  292. static void
  293. l_llll (fn, p)
  294.      long (*fn)();
  295.      struct value * p;
  296. {
  297.   p[0].Int = fn (p[0].Int, p[1].Int, p[2].Int, p[3].Int);
  298. }
  299.  
  300. static void
  301. l_s (fn, p)
  302.      long (*fn)();
  303.      struct value * p;
  304. {
  305.   p[0].Int = fn (p[0].String);
  306.   p[0].type = TYP_INT;
  307. }
  308.  
  309.  
  310.  
  311. #define CALLER(FN,CALL,VIA) static void FN (p) struct value * p; { VIA(CALL,p); }
  312.  
  313. CALLER(do_hms_to_time, dt_hms_to_time, l_lll)
  314. CALLER(do_dhms_to_time, dt_dhms_to_time, l_llll)
  315. CALLER(do_time_to_d, dt_time_to_d, l_l)
  316. CALLER(do_time_to_h, dt_time_to_h, l_l)
  317. CALLER(do_time_to_m, dt_time_to_m, l_l)
  318. CALLER(do_time_to_s, dt_time_to_s, l_l)
  319. CALLER(do_ymd_dst, dt_ymd_dst, l_llll)
  320. CALLER(do_ymd, dt_ymd, l_lll)
  321. CALLER(do_local_year, dt_local_year, l_l)
  322. CALLER(do_local_month, dt_local_month, l_l)
  323. CALLER(do_local_date, dt_local_date, l_l)
  324. CALLER(do_local_hour, dt_local_hour, l_l)
  325. CALLER(do_local_min, dt_local_min, l_l)
  326. CALLER(do_local_sec, dt_local_sec, l_l)
  327. CALLER(do_local_isdst, dt_local_isdst, l_l)
  328. CALLER(do_local_yday, dt_local_yday, l_l)
  329. CALLER(do_local_wday, dt_local_wday, l_l)
  330. CALLER(do_gmt_year, dt_gmt_year, l_l)
  331. CALLER(do_gmt_month, dt_gmt_month, l_l)
  332. CALLER(do_gmt_date, dt_gmt_date, l_l)
  333. CALLER(do_gmt_hour, dt_gmt_hour, l_l)
  334. CALLER(do_gmt_min, dt_gmt_min, l_l)
  335. CALLER(do_gmt_sec, dt_gmt_sec, l_l)
  336. CALLER(do_gmt_isdst, dt_gmt_isdst, l_l)
  337. CALLER(do_gmt_yday, dt_gmt_yday, l_l)
  338. CALLER(do_gmt_wday, dt_gmt_wday, l_l)
  339. CALLER(do_get_date, dt_get_date, l_s)
  340. CALLER(do_posix_date, dt_posix_date, l_s)
  341.  
  342.  
  343.  
  344. void
  345. do_strftime (p)
  346.      struct value * p;
  347. {
  348.   p[0].String = dt_strftime (p[0].String, p[1].Int);
  349. }
  350.  
  351.  
  352.  
  353.  
  354. struct function date_funs[] =
  355. {
  356.   {C_FN3, X_A3, "III", do_hms_to_time, "hms_to_time"},
  357.   {C_FN4, X_A4, "IIII", do_dhms_to_time, "dhms_to_time"},
  358.   {C_FN1, X_A1, "I", do_time_to_d, "time_to_d"},
  359.   {C_FN1, X_A1, "I", do_time_to_h, "time_to_h"},
  360.   {C_FN1, X_A1, "I", do_time_to_m, "time_to_m"},
  361.   {C_FN1, X_A1, "I", do_time_to_s, "time_to_s"},
  362.   {C_FN3, X_A3, "III", do_ymd, "ymd"},
  363.   {C_FN4, X_A4, "IIII", do_ymd_dst, "ymd_dst"},
  364.   {C_FN1, X_A1, "I", do_local_year, "local_year"},
  365.   {C_FN1, X_A1, "I", do_local_month, "local_month"},
  366.   {C_FN1, X_A1, "I", do_local_date, "local_date"},
  367.   {C_FN1, X_A1, "I", do_local_hour, "local_hour"},
  368.   {C_FN1, X_A1, "I", do_local_min, "local_min"},
  369.   {C_FN1, X_A1, "I", do_local_sec, "local_sec"},
  370.   {C_FN1, X_A1, "I", do_local_isdst, "local_isdst"},
  371.   {C_FN1, X_A1, "I", do_local_yday, "local_yday"},
  372.   {C_FN1, X_A1, "I", do_local_wday, "local_wday"},
  373.   {C_FN1, X_A1, "I", do_gmt_year, "gmt_year"},
  374.   {C_FN1, X_A1, "I", do_gmt_month, "gmt_month"},
  375.   {C_FN1, X_A1, "I", do_gmt_date, "gmt_date"},
  376.   {C_FN1, X_A1, "I", do_gmt_hour, "gmt_hour"},
  377.   {C_FN1, X_A1, "I", do_gmt_min, "gmt_min"},
  378.   {C_FN1, X_A1, "I", do_gmt_sec, "gmt_sec"},
  379.   {C_FN1, X_A1, "I", do_gmt_isdst, "gmt_isdst"},
  380.   {C_FN1, X_A1, "I", do_gmt_yday, "gmt_yday"},
  381.   {C_FN1, X_A1, "I", do_gmt_wday, "gmt_wday"},
  382.   {C_FN1, X_A1, "S", do_get_date, "get_date"},
  383.   {C_FN1, X_A1, "S", do_posix_date, "posix_date"},
  384.   {C_FN2, X_A2, "SI", do_strftime, "strftime"},
  385.   {0, 0, 0, 0}
  386. };
  387.